//
// Created by feng on 19-3-29.
// PS: Define the rectangle grid data structure.
//

/*
    矩形网格，三个方向上的格子数目为[subgrid_num_]
*/
#ifndef SOLARENERGY_CHIER_RECTGRID_CUH
#define SOLARENERGY_CHIER_RECTGRID_CUH

#include "CudaGrid.cuh"

namespace solar::cuda
{
    class CudaRectangleGrid : public CudaGrid
    {
        public:
            void Cinit() override;
            void CClear() override;
            // Set *d_grid_helio_match_, *d_grid_helio_index_ and num_grid_helio_match_
            auto CGridHelioMatch(const std::vector<CudaHeliostat*>& h_helios) -> int override;

            __device__ __host__ CudaRectangleGrid() = default;

            __device__ __host__ ~CudaRectangleGrid() override
            {
                if (d_grid_helio_match_)
                    d_grid_helio_match_ = nullptr;
                if (d_grid_helio_index_)
                    d_grid_helio_match_ = nullptr;
            }

            __device__ __host__ auto getSubGridNumber() const -> int3 { return subgrid_num_; }

            void setGridNumber(int3 grid_num_);

            __device__ __host__ auto getDeviceGridHeliostatMatch() const -> int*
            {
                return d_grid_helio_match_;
            }

            void setDeviceGridHeliostatMatch(int* d_grid_helio_match_);

            __device__ __host__ auto getDeviceGridHeliostatIndex() const -> int*
            {
                return d_grid_helio_index_;
            }

            void setDeviceGridHeliostatIndex(int* d_grid_helio_index_);

            [[nodiscard]] auto getNumberOfGridHeliostatMatch() const -> size_t;
            void setNumberOfGridHeliostatMatch(size_t num_grid_helio_match_);

            int3 subgrid_num_{};          // consists of x * y * z sub-grids.
            int* d_grid_helio_match_{}; // size = num_grid_helio_match
            int* d_grid_helio_index_{}; // size = size.x * size.y * size.z + 1
            size_t num_grid_helio_match_{};
    };
} // namespace solar::cuda

#endif // SOLARENERGY_CHIER_RECTGRID_CUH
